package com.example.concurrent;

import org.junit.Test;

import java.util.concurrent.TimeUnit;

public class TThread {

    @Test
    public void caughtThreadException() {
        var thread = new Thread(() -> {
            System.out.println("开始执行线程");
            throw new RuntimeException("我是异常");
        }, "子线程");

        thread.setUncaughtExceptionHandler((t, e) -> {
            System.out.println(t.getName() + " 发生了异常,原因是因为:" + e.getCause());
        });

        thread.start();
    }

    public static void main(String[] args) {
        var thread = new Thread(() -> {
            System.out.println("开始执行线程");
            throw new RuntimeException("我是异常");
        }, "子线程");

        thread.setUncaughtExceptionHandler((t, e) -> {
            System.out.println(t.getName() + " 发生了异常,原因是因为:" + e.getMessage());
        });

//        thread.setPriority();

        thread.start();
    }

    @Test
    public void testJoin() throws InterruptedException {
        var thread = new Thread(() -> {
            System.out.println("开始执行线程");
            try {
                Thread.sleep(TimeUnit.SECONDS.toMillis(5));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "子线程");

        thread.start();
        thread.join();

        System.out.println("主线程");
    }


    class MyThread implements Runnable {
        private Thread t;

        public MyThread(Thread t) {
            this.t = t;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(TimeUnit.SECONDS.toMillis(5));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (MyThread.class) {
                t.notifyAll();
            }
        }
    }

    @Test
    public void testWaitNotify() throws InterruptedException {
        var myThread = new MyThread(Thread.currentThread());
        new Thread(myThread).start();
//        synchronized (MyThread.class) {
//            myThread.wait();
//        }

        System.out.println("主线程");
    }


    private ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
    private InheritableThreadLocal<Integer> inheritableThreadLocal = new InheritableThreadLocal<>();

    public class MyThreadLocalThread extends Thread {
        @Override
        public void run() {
            System.out.println("线程:" + threadLocal.get());
        }
    }

    @Test
    public void threadLocalTest() {
        threadLocal.set(123);
        System.out.println("main thread:" + threadLocal.get());

        new MyThreadLocalThread()
                .start();
    }



    public class MyInheritableThreadLocalThread implements Runnable {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + ":" + inheritableThreadLocal.get());
        }
    }

    @Test
    public void inheritableThreadLocalTest() throws InterruptedException {
        inheritableThreadLocal.set(123);
        System.out.println("main thread:" + inheritableThreadLocal.get());

        var t = new MyInheritableThreadLocalThread();
        new Thread(t, "线程一")
                .start();
        new Thread(t, "线程二")
                .start();


        Thread.sleep(1000);
    }
}
